#lang racket

(require "rename-mutable-pair-ops.rkt")

(provide make-table insert! lookup print-table)


(define (make-table same-key?)
  (let ((tab (list '*table*)))
    (define (assoc key records)
      (cond ((null? records) false)
            ((same-key? key (car (car records))) (car records))
            (else (assoc key (cdr records)))))
    (define (lookup key)
      (let ((record (assoc key (cdr tab))))
        (if record
            (cdr record)
            false)))
    (define (insert! key value)
      (let ((record (assoc key (cdr tab))))
        (if record
            (set-cdr! record value)
            (set-cdr! tab
                      (cons (cons key value) (cdr tab))))))
    (define (print-table)
      (print-list (cdr tab)))
    (define (dispatch m)
      (cond ((eq? m 'lookup) lookup)
            ((eq? m 'insert!) insert!)
            ((eq? m 'print-table) print-table)
            (else (error "unknown operation -- TABLE: " m))))
    dispatch))

(define (lookup key table) ((table 'lookup) key))

(define (insert! key value table) ((table 'insert!) key value))

(define (print-table table) ((table 'print-table)))